

package Cliente_Socket;

import java.io.*;
import java.net.*;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

import Servidor_Socket.IMensaje;
import Servidor_Socket.Mensaje;


public class ClienteSocket {

    private Socket socket;
    private ObjectOutputStream output;
    private ObjectInputStream input;

    private String login;
    private String clave;

    private long nonce1;
    private String cadena_base_datos;

    public boolean conectar(String ip, int puerto, String login, String clave) {
      
    	boolean conectado = true;
        try {
            this.login = login;
            this.clave = clave;
            //System.out.println("Password en el cliente");
            //System.out.println(clave);
            socket = new Socket(ip, puerto);
            output = new ObjectOutputStream(socket.getOutputStream());
            input = new ObjectInputStream(socket.getInputStream());
            
            if (inicioConexion()) {
            		if (recibirChallenge()) {
            				if (!socket.isClosed()) {
            						if (!recibirValidacion())
            							conectado = false;
            						} else {
            							conectado = false;
            				}
            			} else {
            				  conectado = false;
                }
            } else {
            		conectado = false;
            }
        } catch (UnknownHostException ex) {
            JOptionPane.showMessageDialog(null, "Host desconocido.","Error",JOptionPane.WARNING_MESSAGE);
            conectado = false;
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Error de conexion.","Error",JOptionPane.WARNING_MESSAGE);
            conectado = false;
        }
        return conectado;
    }

    
    
    public boolean inicioConexion() {
    	
        Mensaje m = new Mensaje();
        m.setCodigo(IMensaje.INICIO_CONEXION);
        m.setDato1(login);
        try {
            output.writeObject(m);
            return true;
        } catch (IOException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public boolean recibirChallenge() {
        boolean ok = true;
        try {
            Mensaje m = (Mensaje) input.readObject();
            if (m.getCodigo() == IMensaje.CHALLENGE) {
                long nonce = (Long) m.getDato1();
                DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
                MD5 md5 = MD5.getInstance();
                String hash = md5.hashData((nonce + dateFormat.format(new Date()) + clave).getBytes());
                System.out.println("Hash del lado del cliente "+ hash);
                Mensaje r = new Mensaje();
                r.setCodigo(IMensaje.RESPONSE);
                r.setDato1(hash);
                output.writeObject(r);
            } else {
                JOptionPane.showMessageDialog(null, (Integer)m.getDato1() + " - " + (String)m.getDato2(), "Error", JOptionPane.WARNING_MESSAGE);
                ok = false;
            }
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            ok = false;
        } catch (IOException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            ok = false;
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            ok = false;
        }
        return ok;
    }

    public boolean recibirValidacion() {
        boolean ok = true;
        try {
            Mensaje m = (Mensaje) input.readObject();
            if (m.getCodigo() == IMensaje.USUARIO_VALIDADO) {
                nonce1 = (Long) m.getDato1();
                cadena_base_datos = (String) m.getDato2();
            } else {
                JOptionPane.showMessageDialog(null, (Integer)m.getDato1() + " - " + (String)m.getDato2(), "Error", JOptionPane.WARNING_MESSAGE);
                ok = false;
            }
        } catch (IOException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            ok = false;
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            ok = false;
        }
        return ok;
    }

    public boolean desconectar() {
        boolean desconectado = true;
        try {
            MD5 md5 = MD5.getInstance();
            String hash = md5.hashData((nonce1 + login + clave).getBytes());
            Mensaje m = new Mensaje();
            m.setCodigo(IMensaje.CIERRE_CONEXION);
            m.setDato1(hash);
            output.writeObject(m);

            if (input.available() > 0) {
                Mensaje e = (Mensaje) input.readObject();
                if (e.getCodigo() == IMensaje.MENSAJE_ERROR) {
                    JOptionPane.showMessageDialog(null, (Integer)m.getDato1() + " - " + (String)m.getDato2(), "Error", JOptionPane.WARNING_MESSAGE);
                    desconectado = false;
                }
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            desconectado = false;
        } catch (IOException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            desconectado = false;
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(ClienteSocket.class.getName()).log(Level.SEVERE, null, ex);
            desconectado = false;
        }
        return desconectado;
    }

    public String getCadenaDB() {
        return cadena_base_datos;
    }

    public String getLogin() {
        return login;
    }

}
